/*
 * 描          述:  <描述>
 * 修  改   人:  Administrator
 * 修改时间:  2019年5月29日
 * <修改描述:>
 */
package com.tx.component.generator.util;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;

import com.tx.component.basicdata.model.BasicData;
import com.tx.component.basicdata.model.BasicDataEnum;
import com.tx.core.exceptions.util.AssertUtils;
import com.tx.core.util.JPAParseUtils;
import com.tx.core.util.JPAParseUtils.JPAColumnInfo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

/**
 * 生成工具类<br/>
 * <功能详细描述>
 * 
 * @author  Administrator
 * @version  [版本号, 2019年5月29日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class JPAGeneratorUtils {
    
    /**
     * 解析实体对象的注释<br/>
     * <功能详细描述>
     * @param beanType
     * @return [参数说明]
     * 
     * @return String [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    public static String parseEntityComment(Class<?> beanType) {
        AssertUtils.notNull(beanType, "beanType is null.");
        String entityComment = beanType.getSimpleName();
        if (beanType.isAnnotationPresent(ApiModel.class)) {
            ApiModel anno = beanType.getAnnotation(ApiModel.class);
            if (StringUtils.isNotBlank(anno.value())) {
                entityComment = anno.value();
                return entityComment;
            } else if (StringUtils.isNotBlank(anno.description())) {
                entityComment = anno.description();
                return entityComment;
            }
        }
        return entityComment;
    }
    
    /**
     * 解析表字段<br/>
     * <功能详细描述>
     * @param beanType
     * @param jpaPropertySimpleTypeFilter
     * @return [参数说明]
     * 
     * @return List<JPAProperty> [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    public static List<EntityPropertyJPAImpl> parseEntityPropertyList(
            Class<?> beanType) {
        AssertUtils.notNull(beanType, "beanType is null.");
        
        //解析jpa属性
        List<JPAColumnInfo> columns = JPAParseUtils.parseTableColumns(beanType);
        List<EntityPropertyJPAImpl> propertyList = columns.stream()
                .map(column -> {
                    return new EntityPropertyJPAImpl(column);
                })
                .collect(Collectors.toList());
        return propertyList;
    }
    
    /**
     * EntityPropertyJPA的实现<br/>
     * <功能详细描述>
     * 
     * @author  PengQingyang
     * @version  [版本号, 2022年10月7日]
     * @see  [相关类/方法]
     * @since  [产品/模块版本]
     */
    public static class EntityPropertyJPAImpl implements EntityProperty {
        
        /** jpaColumn的信息 */
        private final JPAColumnInfo jpaColumnInfo;
        
        /** 验证表达式 */
        private String validateExpression;
        
        /** <默认构造函数> */
        public EntityPropertyJPAImpl(JPAColumnInfo column) {
            this.jpaColumnInfo = column;
        }
        
        /**
         * @return 返回 validateExpression
         */
        @Override
        public String getValidateExpression() {
            return validateExpression;
        }
        
        /**
         * @param 对validateExpression进行赋值
         */
        @Override
        public void setValidateExpression(String validateExpression) {
            this.validateExpression = validateExpression;
        }
        
        /**
         * @return
         */
        @Override
        public boolean isEnum() {
            return this.jpaColumnInfo.getPropertyType().isEnum();
        }
        
        /**
         * @return
         */
        @Override
        public boolean isBasicdataEnum() {
            return this.jpaColumnInfo.getPropertyType().isEnum()
                    && BasicDataEnum.class.isAssignableFrom(
                            this.jpaColumnInfo.getPropertyType());
        }
        
        /**
         * @return
         */
        @Override
        public boolean isBasicdataType() {
            return BasicData.class
                    .isAssignableFrom(this.jpaColumnInfo.getPropertyType());
        }
        
        /**
         * @return
         */
        @Override
        public String getPropertyReadMethodName() {
            return this.jpaColumnInfo.getPropertyDescriptor()
                    .getReadMethod()
                    .getName();
        }
        
        /**
         * @return
         */
        @Override
        public String getPropertyTypeName() {
            return this.jpaColumnInfo.getPropertyType().getName();
        }
        
        /**
         * @return
         */
        @Override
        public String getPropertyTypeSimpleName() {
            return this.jpaColumnInfo.getPropertyType().getSimpleName();
        }
        
        /**
         * @return
         */
        @Override
        public boolean isPrimaryKey() {
            return this.jpaColumnInfo.isPrimaryKey();
        }
        
        /**
         * @return
         */
        @Override
        public String getPropertyName() {
            return this.jpaColumnInfo.getPropertyName();
        }
        
        /**
         * @return
         */
        @Override
        public boolean isSimpleValueType() {
            return this.jpaColumnInfo.isSimpleValueType();
        }
        
        /**
         * @return
         */
        @Override
        public String getColumnName() {
            return this.jpaColumnInfo.getColumnName();
        }
        
        /**
         * @return
         */
        @Override
        public String getColumnPropertyName() {
            return this.jpaColumnInfo.getColumnPropertyName();
        }
        
        /**
         * @return
         */
        @Override
        public String getColumnPropertyTypeName() {
            return this.jpaColumnInfo.getColumnPropertyType().getName();
        }
        
        /**
         * @return
         */
        @Override
        public String getColumnPropertyTypeSimpleName() {
            return this.jpaColumnInfo.getColumnPropertyType().getSimpleName();
        }
        
        /**
         * @return
         */
        @Override
        public boolean isNullable() {
            return this.jpaColumnInfo.isNullable();
        }
        
        /**
         * @return
         */
        @Override
        public int getLength() {
            return this.jpaColumnInfo.getLength();
        }
        
        /**
         * @return
         */
        @Override
        public int getPrecision() {
            return this.jpaColumnInfo.getPrecision();
        }
        
        /**
         * @return
         */
        @Override
        public int getScale() {
            return this.jpaColumnInfo.getScale();
        }
        
        /**
         * @return
         */
        @Override
        public boolean isUnique() {
            return this.jpaColumnInfo.isUnique();
        }
        
        /**
         * @return
         */
        @Override
        public boolean isInsertable() {
            return this.jpaColumnInfo.isInsertable();
        }
        
        /**
         * @return
         */
        @Override
        public boolean isUpdatable() {
            return this.jpaColumnInfo.isUpdatable();
        }
        
        /**
         * 获取字段描述<br/>
         * <功能详细描述>
         * @return [参数说明]
         * 
         * @return String [返回类型说明]
         * @exception throws [异常类型] [异常说明]
         * @see [类、类#方法、类#成员]
         */
        @Override
        public String getPropertyComment() {
            String propertyComment = getPropertyName();
            if (this.jpaColumnInfo.getTypeDescriptor()
                    .hasAnnotation(ApiModelProperty.class)) {
                ApiModelProperty anno = this.jpaColumnInfo.getTypeDescriptor()
                        .getAnnotation(ApiModelProperty.class);
                if (StringUtils.isNotBlank(anno.value())) {
                    propertyComment = anno.value();
                    return propertyComment;
                }
            }
            switch (propertyComment) {
                case "id":
                    propertyComment = "ID";
                    break;
                case "parentId":
                    propertyComment = "上级ID";
                    break;
                case "code":
                    propertyComment = "编码";
                    break;
                case "type":
                    propertyComment = "类型";
                    break;
                case "typeId":
                    propertyComment = "类型ID";
                    break;
                case "category":
                    propertyComment = "分类";
                    break;
                case "categoryId":
                    propertyComment = "分类ID";
                    break;
                case "catalog":
                    propertyComment = "目录";
                    break;
                case "catalogId":
                    propertyComment = "目录ID";
                    break;
                case "name":
                    propertyComment = "名称";
                    break;
                case "value":
                    propertyComment = "值";
                    break;
                case "valid":
                    propertyComment = "是否有效";
                    break;
                case "modifiable":
                    propertyComment = "是否可编辑";
                    break;
                case "modifyAble":
                    propertyComment = "是否可编辑";
                    break;
                case "remark":
                    propertyComment = "备注";
                    break;
                case "description":
                    propertyComment = "描述";
                    break;
                case "createDate":
                    propertyComment = "创建时间";
                    break;
                case "createOperatorId":
                    propertyComment = "创建人ID";
                    break;
                case "lastUpdateDate":
                    propertyComment = "最后更新时间";
                    break;
                case "lastUpdateOperatorId":
                    propertyComment = "最后更新人ID";
                    break;
                case "effictiveDate":
                    propertyComment = "生效时间";
                    break;
                case "expiryDate":
                    propertyComment = "到期时间";
                    break;
            }
            return propertyComment;
        }
        
        /**
         * @return 返回 jpaColumnInfo
         */
        public JPAColumnInfo getJpaColumnInfo() {
            return jpaColumnInfo;
        }
    }
}
